import { usePhoneStore } from '@/store/modules/phone'
import { ElMessage } from 'element-plus'

import * as AgentApi from '@/api/call/agent'

import { useBoxPhone } from './useBoxPhone'
import { useWebPhone } from './useWebPhone'
import { useSimPhone } from './useSimPhone'
import { useRecallPhone } from './useRecallPhone'

/**
 * 卡尔无线话机盒子sdk
 * 1. 使用ws连接到本地
 * 2. 使用指令交互，完成时间同步，呼叫，来电和去电接听
 *
 * okcc sip 话机
 * 1. ws 连接远端
 * 2. api接口发起call，获取reqNo，本地ws 继续发送外呼指令到远端
 */

let instance = null
let useStore = null
let boxPhone = null
let webPhone = null
let simPhone = null
let recallPhone = null

class WebPhone {
  constructor() {
    if (instance) {
      return instance
    }
    // instance = this
    useStore = usePhoneStore()
    boxPhone = useBoxPhone()
    webPhone = useWebPhone()
    simPhone = useSimPhone()
    recallPhone = useRecallPhone()
  }

  reg() {
    if (useStore.phoneMode == 'box') {
      boxPhone.reg()
    } else if (useStore.phoneMode == 'sip') {
      webPhone.reg()
    } else if (useStore.phoneMode == 'recall') {
      recallPhone.reg()
    } else if (useStore.phoneMode == 'sim') {
      simPhone.reg()
    }
  }

  /**
   * {
   *
   *  source: ent、customer/contact/clue/none(手拨)
   *  sourceId: ent.id, customer.id, contact.id, clue.id
   *  callee: 被叫号码
   *
   * }
   * @param params
   */
  call(params) {
    // 防抖逻辑
    // console.info('call me  ----- ', params)
    if (!useStore.channelId || !useStore.phoneMode) {
      ElMessage.error('未登录话机')
      useStore.setIsDialog(true)
      return // 提前返回，避免后续逻辑执行
    }
    const req = {
      ...params,
      channelId: useStore.channelId
    }
    if (useStore.phoneMode == 'box') {
      boxPhone.call(req)
    } else if (useStore.phoneMode == 'sip') {
      webPhone.call(req)
    } else if (useStore.phoneMode == 'recall' || useStore.phoneMode == 'sim') {
      AgentApi.simpleCall(req).then((res) => {
        if (res.success) {
          localStorage.setItem('CALL_TASK_REQ_NO', res.reqNo)
          ElMessage.success('呼叫已发送，请注意手机接听')
        } else {
          ElMessage.error(res.message)
        }
      })
    }
  }

  /**
   * 执行群呼任务， 需要启动一个异步线程
   * 1. 传入taskId -> 得到呼叫号码参数
   * 2. 执行单点call 方法， 缓存reqNo
   * 3. 异步线程 监听这个 reqNo ， 去后台查找话单，如果为空，表示收到话单推送（结束通话）
   * 4. 根据3， 判断是否继续执行下一个话单 -> 1
   * @param taskId
   */
  batchTaskCall(task) {
    this.stopTaskCall()
    // 必须设置一个缓存， 当前必须在执行任务；
    setTimeout(() => {
      this.getNumberAndExec(task.id)
    }, 3000)

    // 启动后每10秒检查一次话单
    setInterval(() => {
      this.setIntervalCall()
    }, 15000)

    // 更新vue store 对象
    useStore.setCallTaskVisible(true)
    useStore.setTaskInfo(task)
  }

  getNumberAndExec(taskId) {
    if (!taskId) {
      return
    }
    AgentApi.getTaskNextNumber(useStore.phoneMode, taskId)
      .then((res) => {
        const { number, source, sourceId, id } = res.numberInfo
        localStorage.setItem('BATCH_TASK_CALL', res.taskInfo)
        useStore.setTaskInfo(res.taskInfo)
        this.call({ callee: number, source: source, sourceId: sourceId, taskId, numberId: id })
        // 放入异步任务
      })
      .catch((e) => {
        localStorage.removeItem('BATCH_TASK_CALL')
      })
  }

  setIntervalCall() {
    const task = localStorage.getItem('BATCH_TASK_CALL')
    if (task != null) {
      // 去查reqNo
      const reqNo = localStorage.getItem('CALL_TASK_REQ_NO')
      if (reqNo) {
        AgentApi.getRecordByReqNo(reqNo).then((res) => {
          // 存在session 但是不存在话单，表示已经入库
          if (!res) {
            this.getNumberAndExec(JSON.parse(task)?.id)
          }
        })
      }
    }
  }

  stopTaskCall() {
    localStorage.removeItem('BATCH_TASK_CALL')
    localStorage.removeItem('CALL_TASK_REQ_NO')
  }

  hangup() {
    if (useStore.phoneMode == 'box') {
      boxPhone.hangup()
    } else if (useStore.phoneMode == 'sip') {
      webPhone.hangup()
    }
  }

  answer() {
    if (useStore.phoneMode == 'sip') {
      webPhone.answer()
    }
  }

  setLogin() {
    if (useStore.phoneMode == 'sip') {
      webPhone.setLogin()
    }
  }

  setLogout() {
    if (useStore.phoneMode == 'sip') {
      webPhone.setLogout()
    }
  }

  setBusy() {
    if (useStore.phoneMode == 'sip') {
      webPhone.setBusy()
    }
  }

  setIdle() {
    if (useStore.phoneMode == 'sip') {
      webPhone.setIdle()
    }
  }

  static getInstance() {
    if (!instance) {
      instance = new WebPhone()
    }
    return instance
  }
}

export default WebPhone
